﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using UnityEngine;
using FibMatrix.IO;
using FM_Mono;
using UnityEngine.Profiling;
using Object = UnityEngine.Object;

namespace FibMatrix.Utils
{
    public static class CommonUtil
    {
        private static char[] _separator = {'*'};

        public static char commaSeparator = ',';
        public static char lineSeparator = '|';

        public const int ONE_DAY_SECONDS = 86400;
        public const int ONE_HOUR_SECONDS = 3600;
        public const int ONE_MINUTE_SENONDS = 60;

        public static int mainThreadId;

        public static void ResetTransform(Transform t)
        {
            t.localPosition = Vector3.zero;
            t.localRotation = Quaternion.identity;
            t.localScale = Vector3.one;
        }

        public static void SetParentToCurrentPosition(Transform t, Transform parent)
        {
            parent.parent = t.parent;
            parent.localPosition = t.localPosition;
            parent.localRotation = t.localRotation;
            parent.localScale = t.localScale;
            t.parent = parent;
        }

        public static Component FindInParent(Type type, GameObject go)
        {
            Component comp = go.GetComponent(type);
            if (comp == null)
            {
                Transform t = go.transform.parent;

                while (t != null && comp == null)
                {
                    comp = t.gameObject.GetComponent(type);
                    t = t.parent;
                }
            }

            return comp;
        }

        public static GameObject GetChildByName(GameObject container, string name, bool recursive = false)
        {
            Transform trans = container.transform;
            int childCount = trans.childCount;
            GameObject child;
            for (int i = 0; i < childCount; ++i)
            {
                child = trans.GetChild(i).gameObject;
                if (child.name == name)
                {
                    return child;
                }

                Transform childTrans = child.transform;
                if (recursive && childTrans.childCount > 0)
                {
                    child = GetChildByName(child, name, true);
                    if (child)
                    {
                        return child;
                    }
                }
            }

            return null;
        }

        public static Transform GetChildByName(Transform container, string name, bool recursive = false)
        {
            int childCount = container.childCount;
            Transform child;
            for (int i = 0; i < childCount; ++i)
            {
                child = container.GetChild(i);
                if (child.gameObject.name == name)
                {
                    return child;
                }

                Transform childTrans = child.transform;
                if (recursive && childTrans.childCount > 0)
                {
                    child = GetChildByName(child, name, true);
                    if (child)
                    {
                        return child;
                    }
                }
            }

            return null;
        }

        public static int[] ConvertStrArr2IntArr(string[] strArr)
        {
            int count = strArr != null ? strArr.Length : 0;
            int[] intArr = null;
            if (count > 0)
            {
                intArr = new int[count];
                ;
                for (int i = 0; i < count; ++i)
                {
                    intArr[i] = int.Parse(strArr[i]);
                }
            }

            return intArr;
        }

        public static float[] ConvertStrArr2FloatArr(string[] strArr, float defaultValue = 0)
        {
            int count = strArr != null ? strArr.Length : 0;
            float[] floatArr = null;
            if (count > 0)
            {
                floatArr = new float[count];
                ;
                for (int i = 0; i < count; ++i)
                {
                    if (string.IsNullOrEmpty(strArr[i]))
                    {
                        floatArr[i] = defaultValue;
                    }
                    else
                    {
                        floatArr[i] = float.Parse(strArr[i]);
                    }
                }
            }

            return floatArr;
        }

        public static string GetStringValue(Hashtable properties, string propertyName)
        {
            string val = properties[propertyName] as string;
            return val;
        }

        public static int GetIntValue(Hashtable properties, string propertyName, int defaultVal = -1)
        {
            string val = properties[propertyName] as string;
            int result = defaultVal;
            if (val != null && int.TryParse(val, out result))
            {
                return result;
            }

            return defaultVal;
        }

        public static int GetIntValue(Hashtable properties, string propertyName, int minVal, int maxVal, int defaultVal)
        {
            int val = GetIntValue(properties, propertyName, defaultVal);
            val = Mathf.Clamp(val, minVal, maxVal);
            return val;
        }

        public static int GetIntValue(string rawVal, int defaultVal = -1)
        {
            int result = defaultVal;
            if (int.TryParse(rawVal, out result))
            {
                return result;
            }

            return defaultVal;
        }

        public static byte GetByteValue(Hashtable properties, string propertyName)
        {
            string val = properties[propertyName] as string;
            byte result = 0;
            if (byte.TryParse(val, out result))
            {
                return result;
            }

            return 0;
        }

        public static int GetShortValue(Hashtable properties, string propertyName)
        {
            string val = properties[propertyName] as string;
            short result = -1;
            if (short.TryParse(val, out result))
            {
                return result;
            }

            return -1;
        }

        public static long GetLongValue(Hashtable properties, string propertyName)
        {
            string val = properties[propertyName] as string;
            long result = -1;
            if (val != null && long.TryParse(val, out result))
            {
                return result;
            }

            return -1;
        }

        public static long GetLongValue(string rawVal)
        {
            long result = -1;
            if (long.TryParse(rawVal, out result))
            {
                return result;
            }

            return -1;
        }

        public static double GetDoubleValue(Hashtable properties, string propertyName)
        {
            string val = properties[propertyName] as string;
            double result = 0;
            if (val != null && double.TryParse(val, NumberStyles.Any, CultureInfo.InvariantCulture, out result))
            {
                return result;
            }

            return 0;
        }

        private static char[] _percentTrimChars = new char[] {'%', ' '};

        public static float GetPercentToFloatValue(Hashtable properties, string propertyName, float defaultVal = 0)
        {
            string val = properties[propertyName] as string;
            val = val.Trim(_percentTrimChars);
            float result = defaultVal;
            if (val != null && float.TryParse(val, NumberStyles.Any, CultureInfo.InvariantCulture, out result))
            {
                return result / 100f;
            }

            return defaultVal;
        }

        public static float GetFloatValue(Hashtable properties, string propertyName, float defaultVal = 0)
        {
            string val = properties[propertyName] as string;
            float result = defaultVal;
            if (val != null && float.TryParse(val, NumberStyles.Any, CultureInfo.InvariantCulture, out result))
            {
                return result;
            }

            return defaultVal;
        }

        public static float GetFloatValue(string rawVal, float defaultVal = 0)
        {
            float result = defaultVal;
            if (float.TryParse(rawVal, NumberStyles.Any, CultureInfo.InvariantCulture, out result))
            {
                return result;
            }

            return defaultVal;
        }

        public static bool GetBoolValue(Hashtable properties, string propertyName, bool defaultVal = false)
        {
            string val = properties[propertyName] as string;
            return GetBoolValue(val, defaultVal);
        }

        public static bool GetBoolValue(string val, bool defaultVal = false)
        {
            bool result = false;
            if (val != null && bool.TryParse(val, out result))
            {
                return result;
            }

            return defaultVal;
        }

        //	public static T DeserializeBinaryData<T>(byte[] rawData) where T :class
        //	{
        //		T info = null;
        //		if (rawData != null)
        //		{
        //			MemoryStream stream = new MemoryStream(rawData);
        //			DeflateStream deflateStream = new DeflateStream(stream, CompressionMode.Decompress);
        //			BinaryFormatter formatter = new BinaryFormatter();
        //			info = (T)formatter.Deserialize(deflateStream);
        //			deflateStream.Close();
        //			deflateStream.Dispose();
        //			stream.Close();
        //			stream.Dispose();
        //		}
        //		return info;
        //	}
        //
        //	public static byte[] SerializeBinaryData<T>(T info) where T :class
        //	{
        //		byte[] bytes = null;
        //		if (info != null)
        //		{
        //			MemoryStream stream = new MemoryStream();
        //			DeflateStream deflateStream = new DeflateStream(stream, CompressionMode.Compress);
        //			BinaryFormatter formatter = new BinaryFormatter();
        //			formatter.Serialize(deflateStream, info);
        //			deflateStream.Flush();
        //			deflateStream.Close();
        //			bytes = stream.ToArray();
        //			deflateStream.Dispose();
        //			stream.Close();
        //			stream.Dispose();
        //		}
        //		return bytes;
        //	}

        public static string[] SplitString(string rawString, char seperator)
        {
            if (string.IsNullOrEmpty(rawString))
            {
                return null;
            }

            _separator[0] = seperator;
            return rawString.Split(_separator);
        }


        public static byte[] SplitStringToByteArray(string rawString, char seperator)
        {
            if (string.IsNullOrEmpty(rawString))
            {
                return null;
            }

            _separator[0] = seperator;
            string[] rawArray = rawString.Split(_separator);
            int count = rawArray.Length;
            if (count > 0)
            {
                byte[] byteArray = new byte[rawArray.Length];
                for (int i = 0; i < count; ++i)
                {
                    byteArray[i] = MathUtil.ParseByte(rawArray[i]);
                }

                return byteArray;
            }

            return null;
        }

        public static int[] SplitStringToIntArray(string rawString, char seperator)
        {
            if (string.IsNullOrEmpty(rawString))
            {
                return null;
            }

            _separator[0] = seperator;
            string[] rawArray = rawString.Split(_separator);
            int count = rawArray.Length;
            if (count > 0)
            {
                int[] intArray = new int[rawArray.Length];
                for (int i = 0; i < count; ++i)
                {
                    intArray[i] = MathUtil.ParseInt(rawArray[i]);
                }

                return intArray;
            }

            return null;
        }

        public static HashSet<int> SplitStringToIntSet(string rawString, char seperator)
        {
            if (string.IsNullOrEmpty(rawString))
            {
                return null;
            }

            _separator[0] = seperator;
            string[] rawArray = rawString.Split(_separator);
            int count = rawArray.Length;
            if (count > 0)
            {
                HashSet<int> intSet = new HashSet<int>();
                for (int i = 0; i < count; ++i)
                {
                    intSet.Add(MathUtil.ParseInt(rawArray[i]));
                }

                return intSet;
            }

            return null;
        }

        public static float[] SplitStringToFloatArray(string rawString, char seperator)
        {
            if (string.IsNullOrEmpty(rawString))
            {
                return null;
            }

            _separator[0] = seperator;
            string[] rawArray = rawString.Split(_separator);
            int count = rawArray.Length;
            if (count > 0)
            {
                float[] intArray = new float[rawArray.Length];
                for (int i = 0; i < count; ++i)
                {
                    intArray[i] = MathUtil.ParseFloat(rawArray[i]);
                }

                return intArray;
            }

            return null;
        }

        public static long[] SplitStringToLongArray(string rawString, char seperator)
        {
            if (string.IsNullOrEmpty(rawString))
            {
                return null;
            }

            _separator[0] = seperator;
            string[] rawArray = rawString.Split(_separator);
            int count = rawArray.Length;
            if (count > 0)
            {
                long[] longArray = new long[rawArray.Length];
                for (int i = 0; i < count; ++i)
                {
                    longArray[i] = MathUtil.ParseLong(rawArray[i]);
                }

                return longArray;
            }

            return null;
        }

        public static Vector3 SplitStringToVector3(string rawString, char seperator)
        {
            if (!string.IsNullOrEmpty(rawString))
            {
                _separator[0] = seperator;
                string[] rawArray = rawString.Split(_separator);
                int count = rawArray.Length;
                if (count == 3)
                {
                    return new Vector3(MathUtil.ParseFloat(rawArray[0]), MathUtil.ParseFloat(rawArray[1]), MathUtil.ParseFloat(rawArray[2]));
                }
            }

            return Vector3.zero;
            ;
        }

        public static Vector2 SplitStringToVector2(string rawString, char seperator)
        {
            if (!string.IsNullOrEmpty(rawString))
            {
                _separator[0] = seperator;
                string[] rawArray = rawString.Split(_separator);
                int count = rawArray.Length;
                if (count == 2)
                {
                    return new Vector2(MathUtil.ParseFloat(rawArray[0]), MathUtil.ParseFloat(rawArray[1]));
                }
            }

            return Vector2.zero;
            ;
        }

        public static Vector4 SplitStringToVector4(string rawString, char seperator)
        {
            if (!string.IsNullOrEmpty(rawString))
            {
                _separator[0] = seperator;
                string[] rawArray = rawString.Split(_separator);
                int count = rawArray.Length;
                if (count == 4)
                {
                    return new Vector4(MathUtil.ParseFloat(rawArray[0]), MathUtil.ParseFloat(rawArray[1]), MathUtil.ParseFloat(rawArray[2]), 
                        MathUtil.ParseFloat(rawArray[3]));
                }
            }

            return Vector4.zero;
        }

        public static Dictionary<string, string> ParseToDictionary(string rawString, char seperator1, char seperator2)
        {
            rawString = rawString.Trim();
            Dictionary<string, string> dict = new Dictionary<string, string>();
            string[] items = SplitString(rawString, seperator1);
            int count = items == null ? 0 : items.Length;
            for (int i = 0; i < count; ++i)
            {
                string[] keyVal = SplitString(items[i], seperator2);
                if (keyVal == null || keyVal.Length < 2)
                {
                    continue;
                }

                dict.Add(keyVal[0], keyVal[1]);
            }

            return dict;
        }

        public static void ParseToDictionary(string rawString, char seperator1, char seperator2,
            out Dictionary<int, float> dict)
        {
            dict = new Dictionary<int, float>();
            if (string.IsNullOrEmpty(rawString))
            {
                return;
            }

            rawString = rawString.Trim();
            string[] items = SplitString(rawString, seperator1);
            int count = items == null ? 0 : items.Length;
            for (int i = 0; i < count; ++i)
            {
                string[] keyVal = SplitString(items[i], seperator2);
                if (keyVal == null || keyVal.Length < 2)
                {
                    continue;
                }

                dict.Add(MathUtil.ParseInt(keyVal[0]), MathUtil.ParseFloat(keyVal[1]));
            }
        }

        public static void ParseToDictionary(string rawString, char seperator1, char seperator2,
            out Dictionary<int, int> dict)
        {
            rawString = rawString.Trim();
            dict = new Dictionary<int, int>();
            string[] items = SplitString(rawString, seperator1);
            int count = items == null ? 0 : items.Length;
            for (int i = 0; i < count; ++i)
            {
                string[] keyVal = SplitString(items[i], seperator2);
                if (keyVal == null || keyVal.Length < 2)
                {
                    continue;
                }

                dict.Add(MathUtil.ParseInt(keyVal[0]), MathUtil.ParseInt(keyVal[1]));
            }
        }

        public static void ParseToDictionary(string rawString, char seperator1, char seperator2,
            out Dictionary<string, int> dict)
        {
            dict = new Dictionary<string, int>();
            if (string.IsNullOrEmpty(rawString))
            {
                return;
            }

            rawString = rawString.Trim();
            string[] items = SplitString(rawString, seperator1);
            int count = items == null ? 0 : items.Length;
            for (int i = 0; i < count; ++i)
            {
                string[] keyVal = SplitString(items[i], seperator2);
                if (keyVal == null || keyVal.Length < 2)
                {
                    continue;
                }

                dict.Add(keyVal[0], MathUtil.ParseInt(keyVal[1]));
            }
        }

        public static List<List<string>> ParseAttributeToList(string rawString, char seperator1, char seperator2)
        {
            List<List<string>> myList = new List<List<string>>();
            string[] tempList = SplitString(rawString, seperator1);
            int count = tempList == null ? 0 : tempList.Length;
            for (int i = 0; i < count; i++)
            {
                string[] tempStringList = SplitString(tempList[i], seperator2);
                List<string> stringList = new List<string>();
                if (tempStringList == null || tempStringList.Length == 0)
                    continue;

                for (int j = 0; j < tempStringList.Length; j++)
                {
                    stringList.Add(tempStringList[j]);
                }

                myList.Add(stringList);
            }

            return myList;
        }

        public static void ParseAttributeToList(string rawString, char seperator1, char seperator2, List<int[]> list)
        {
            string[] tempList = SplitString(rawString, seperator1);
            int count = tempList == null ? 0 : tempList.Length;
            for (int i = 0; i < count; i++)
            {
                list.Add(SplitStringToIntArray(tempList[i], seperator2));
            }
        }


        public static string GetGameObjectFullPath(GameObject go)
        {
            List<string> path = new List<string>();

            Transform current = go.transform;
            path.Add(current.name);

            while (current.parent != null)
            {
                path.Insert(0, current.parent.name);
                current = current.parent;
            }

            return string.Join("/", path.ToArray());
        }

    // public static GameObject PoolAllocate(string prefabPath, int preAllocateCount = 10, Transform newParent = null)
    //    {
    //        GameObject template = ResourceFacade.instance.LoadPrefab(prefabPath, ResourceLoadMode.UnRef);
    //        if (template != null)
    //        {
    // 		return GameObjectPool2.instance.Spawn(template, preAllocateCount, true, null, newParent);
    //        }
    //        return null;
    //    }

//    public static UIFollowTarget AddFollowComponent(GameObject viewObject, Transform anchor)
//    {
//        return AddFollowComponent(viewObject, anchor, HUDRoot.go);
//    }

        // public static UIFollowTarget AddFollowComponent(GameObject viewObject, Transform anchor, GameObject parent)
        // {
        //     if (anchor == null)
        //     {
        //         Debug.Log("Error! " + viewObject + parent);
        //     }
        //
        //     if (parent != null)
        //     {
        //         NGUITools.AddChildWithoutCreate(parent, viewObject);
        //     }
        //     UIFollowTarget follow = viewObject.GetComponent<UIFollowTarget>();
        //     if (follow == null)
        //     {
        //         follow = viewObject.AddComponent<UIFollowTarget>();
        //     }
        //     if (anchor != null)
        //     {
        //         follow.target = anchor;
        //         follow.enabled = true;
        //
        //     }
        //     follow.gameCamera = UIContainer.mainCamera;
        //     follow.uiCamera = UIContainer.uiCamera;
        //     return follow;
        // }

        public static void ClearChildren(Transform container)
        {
            int count = container ? container.childCount : 0;
            for (int i = count - 1; i >= 0; --i)
            {
                Transform child = container.GetChild(i);
                child.parent = null;
                GameObject.Destroy(child.gameObject);
            }
        }

        public static Vector2[] DEFAULT_UVS = new[]
        {
            new Vector2(0, 0),
            new Vector2(0, 1),
            new Vector2(1, 1),
            new Vector2(1, 0)
        };

        public static int[] DEFAULT_TRIANGLES = new[] {0, 1, 2, 0, 2, 3};

        public static Mesh CreateXYPlaneMesh(float halfW, float halfH, Vector3[] verts, Vector2[] uvs, int[] triangles,
            bool needNormals = false)
        {
            Mesh m = new Mesh();
            m.name = "ScriptedMesh";
            m.vertices = verts ?? new Vector3[]
            {
                new Vector3(halfW, -halfH, 0f),
                new Vector3(halfW, halfH, 0f),
                new Vector3(-halfW, halfH, 0f),
                new Vector3(-halfW, -halfH, 0f)
            };
            m.uv = uvs ?? DEFAULT_UVS;

            m.triangles = triangles ?? DEFAULT_TRIANGLES;

            if (needNormals)
            {
                m.RecalculateNormals();
            }

            return m;
        }

        public static Vector2[] DEFAULT_INVERT_UVS = new[]
        {
            new Vector2(0, 0),
            new Vector2(0, 1),
            new Vector2(1, 1),
            new Vector2(1, 0)
        };

        public static int[] DEFAULT_INVERT_TRIANGLES = new[] {0, 3, 2, 0, 2, 1};

//    public static Mesh CreateInvertXYPlaneMesh(float halfW, float halfH, Vector3[] verts, Vector2[] uvs, int[] triangles, bool needNormals = false)
//    {
//        Mesh m = new Mesh();
//        m.name = "ScriptedMesh";
//        m.vertices = verts ?? new Vector3[] {
//            new Vector3(-halfW, -halfH, 0f),
//            new Vector3(halfW, halfH, 0f),
//            new Vector3(halfW, -halfH, 0f),
//            new Vector3(-halfW, halfH, 0f)
//        };
//		m.uv = uvs ?? DEFAULT_INVERT_UVS;
//
//        m.triangles = triangles ?? DEFAULT_INVERT_TRIANGLES;
//
//        if (needNormals)
//        {
//            m.RecalculateNormals();
//        }
//
//        return m;
//    }

        // public static Vector3 GetTouchWorldPos()
        // {
        //     return UICamera.currentCamera.ScreenToWorldPoint(UICamera.currentTouch.pos);
        // }

//     public static byte[] ReadStreamingAsset(string relativePath)
//     {
// #if UNITY_ANDROID && !UNITY_EDITOR
// 		bool isMainThread = Thread.CurrentThread.ManagedThreadId == mainThreadId;
// 		if (!isMainThread)
// 		{
// 			AndroidJNI.AttachCurrentThread();
// 		}
// 		byte[] result = AndroidUtil.ReadStreamingAsset(relativePath, true);
// 		if (!isMainThread)
// 		{
// 			AndroidJNI.DetachCurrentThread();
// 		}
// 		return result;
// #else
//         return File.ReadAllBytes(FibMatrix.IO.PackageManager.streamingAssetsPath + "/" + relativePath);
// #endif
//     }

        public static int ParseApkVersionToNumber(string version)
        {
            if (version.Contains("."))
            {
                int[] versions = SplitStringToIntArray(version, '.');
                if (versions != null && versions.Length == 3)
                {
                    return versions[0] * 10000 + versions[1] * 100 + versions[2];
                }
            }

            return int.MaxValue;
        }

        public static int GetAppVersionNumber(string version)
        {
            int versionNumber = 0;
            if (!string.IsNullOrEmpty(version))
            {
                string[] versions = version.Split('.');
                if (versions.Length == 3)
                {
                    try
                    {
                        int majorVersion = MathUtil.ParseInt(versions[0]) * 10000;
                        int minorVersion = MathUtil.ParseInt(versions[1]) * 100;
                        int revisionNumber = MathUtil.ParseInt(versions[2]);
                        versionNumber = majorVersion + minorVersion + revisionNumber;
                    }
                    catch (Exception e)
                    {
                        Debug.LogException(e);
                    }
                }
            }

            return versionNumber;
        }

        // public static T ReadValue<T>(this JObject jo, string key, T defaultValue)
        // {
        //     JToken val;
        //     if (jo.TryGetValue(key, out val))
        //         return val.Value<T>();
        //     return defaultValue;
        // }

        // public static bool ReadValue<T>(this JObject jo, string key, ref T property)
        // {
        //     JToken val;
        //     if (jo.TryGetValue(key, out val))
        //     {
        //         property = val.Value<T>();
        //         return true;
        //     }
        //     return false;
        // }

        // public static bool HasValue(this JObject jo, string key)
        // {
        //     return (jo as IDictionary<string, JToken>).ContainsKey(key);
        // }

        public static string GetRomanNumber(int number)
        {
            int[] arabic = new int[13];
            string[] roman = new string[13];
            int i = 0;
            string o = "";

            arabic[0] = 1000;
            arabic[1] = 900;
            arabic[2] = 500;
            arabic[3] = 400;
            arabic[4] = 100;
            arabic[5] = 90;
            arabic[6] = 50;
            arabic[7] = 40;
            arabic[8] = 10;
            arabic[9] = 9;
            arabic[10] = 5;
            arabic[11] = 4;
            arabic[12] = 1;

            roman[0] = "M";
            roman[1] = "CM";
            roman[2] = "D";
            roman[3] = "CD";
            roman[4] = "C";
            roman[5] = "XC";
            roman[6] = "L";
            roman[7] = "XL";
            roman[8] = "X";
            roman[9] = "IX";
            roman[10] = "V";
            roman[11] = "IV";
            roman[12] = "I";

            while (number > 0)
            {
                while (number >= arabic[i])
                {
                    number = number - arabic[i];
                    o = o + roman[i];
                }

                i++;
            }

            return o;
        }

        public static bool IsInMethodCallStack(string methodName)
        {
#if UNITY_EDITOR
            System.Diagnostics.StackTrace stackTrace = new System.Diagnostics.StackTrace(); // get call stack
            System.Diagnostics.StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames)

            foreach (var stackFrame in stackFrames)
            {
                if (stackFrame.GetMethod().Name == methodName)
                {
                    return true;
                }
            }

            return false;
#else
        return true;
#endif
        }

        //格式化战斗力数据
        public static string FormatFightCapacity(long FightCapacity)
        {
            if (FightCapacity >= 1000000)
            {
                return (FightCapacity * 1.0000f / 1000000).ToString("0.00") + "m";
            }

            if (FightCapacity >= 1000)
            {
                return (FightCapacity * 1.0000f / 1000).ToString("0.00") + "k";
            }

            return FightCapacity.ToString();
        }

        public static int WriteInt2BEBytes(byte[] b, int data, int pos)
        {
            b[pos + 3] = (byte) data;
            b[pos + 2] = (byte) (((uint) data >> 8) & 0xFF);
            b[pos + 1] = (byte) (((uint) data >> 16) & 0xFF);
            b[pos] = (byte) (((uint) data >> 24) & 0xFF);
            return pos + 4;
        }

        public static int ReadIntFromBEBytes(byte[] b, int pos)
        {
            int val = 0;
            val |= b[pos] << 24;
            val |= b[pos + 1] << 16;
            val |= b[pos + 2] << 8;
            val |= b[pos + 3];
            return val;
        }

        public static int WriteShort2BEBytes(byte[] b, short data, int pos)
        {
            b[pos + 1] = (byte) data;
            b[pos] = (byte) (((uint) data >> 8) & 0xFF);
            return pos + 2;
        }

        public static short ReadShortFromBEBytes(byte[] b, int pos)
        {
            int val = 0;
            val |= b[pos] << 8;
            val |= b[pos + 1];
            return (short) val;
        }

        private static byte[] _cacheBytes = new byte[4];

        public static void WriteInt2BEBytes(Stream s, int data)
        {
            _cacheBytes[3] = (byte) data;
            _cacheBytes[2] = (byte) (((uint) data >> 8) & 0xFF);
            _cacheBytes[1] = (byte) (((uint) data >> 16) & 0xFF);
            _cacheBytes[0] = (byte) (((uint) data >> 24) & 0xFF);
            s.Write(_cacheBytes, 0, 4);
        }

        public static int ReadIntFromBEBytes(Stream s, int pos = -1)
        {
            if (pos >= 0)
            {
                s.Position = pos;
            }

            s.Read(_cacheBytes, 0, 4);
            int val = 0;
            val |= _cacheBytes[0] << 24;
            val |= _cacheBytes[1] << 16;
            val |= _cacheBytes[2] << 8;
            val |= _cacheBytes[3];
            return val;
        }

        public static void WriteShort2BEBytes(Stream s, short data)
        {
            _cacheBytes[1] = (byte) data;
            _cacheBytes[0] = (byte) (((uint) data >> 8) & 0xFF);
            s.Write(_cacheBytes, 0, 2);
        }

        public static short ReadShortFromBEBytes(Stream s, int pos = -1)
        {
            if (pos >= 0)
            {
                s.Position = pos;
            }

            s.Read(_cacheBytes, 0, 2);
            int val = 0;
            val |= _cacheBytes[0] << 8;
            val |= _cacheBytes[1];
            return (short) val;
        }

        public static void MemSet(byte[] array, byte value)
        {
            if (array == null)
            {
                throw new ArgumentNullException("array");
            }

            int block = 32, index = 0;
            int length = Math.Min(block, array.Length);

            //Fill the initial array
            while (index < length)
            {
                array[index++] = value;
            }

            length = array.Length;
            while (index < length)
            {
                Buffer.BlockCopy(array, 0, array, index, Math.Min(block, length - index));
                index += block;
                block *= 2;
            }
        }

        public static string GetStringHash(string strToEncrypt)
        {
            System.Text.UTF8Encoding ue = new System.Text.UTF8Encoding();
            byte[] bytes = ue.GetBytes(strToEncrypt);
            return GetBytesHash(bytes);
        }

        public static string GetBytesHash(byte[] data)
        {
            try
            {
                MD5 md5 = new MD5CryptoServiceProvider();
                byte[] result = md5.ComputeHash(data);
                return BitConverter.ToString(result);
                ;
            }
            catch (Exception e)
            {
                Debug.LogError(e.Message);
                return "";
            }
        }

        public static void SetGameObjectLayer(GameObject go, int layer)
        {
            go.layer = layer;
            Transform trans = go.transform;
            int count = trans.childCount;
            for (int i = 0; i < count; ++i)
            {
                SetGameObjectLayer(trans.GetChild(i).gameObject, layer);
            }
        }

        public static void DeleteDir(string path)
        {
            StorageManager.DeleteDirectory(path, true);
        }

        private static StringBuilder _cacheSB = new StringBuilder(100);

        public static string GetBytesMD5(byte[] bytes)
        {
            using (var md5 = MD5.Create())
            {
                byte[] hash = md5.ComputeHash(bytes);
                _cacheSB.Clear();
                for (int i = 0, l = hash.Length; i < l; ++i)
                {
                    _cacheSB.Append(hash[i].ToString("x2"));
                }

                return _cacheSB.ToString();
            }
        }

        public static string GetFileMD5(string filePath)
        {
            using (var fs = File.OpenRead(filePath))
            {
                return GetStreamMD5(fs);
            }
        }

        public static string GetStreamMD5(Stream stream)
        {
            using (var md5 = MD5.Create())
            {
                byte[] hash = md5.ComputeHash(stream);
                _cacheSB.Clear();
                for (int i = 0, l = hash.Length; i < l; ++i)
                {
                    _cacheSB.Append(hash[i].ToString("x2"));
                }

                return _cacheSB.ToString();
            }
        }

        [IgnoreGen]
        public static bool StartsWith(string str, string compareStr)
        {
            if (str != null && compareStr != null && str.Length >= compareStr.Length)
            {
                var len = compareStr.Length;
                for (int i = 0; i < len; ++i)
                {
                    if (str[i] != compareStr[i])
                    {
                        return false;
                    }
                }

                return true;
            }

            return false;
        }
        
        public static bool IsNull(this Object com)
        {
            return com == null;
        }
        public static bool IsNotNull(this Object com)
        {
            return com != null;
        }

        public static void BeginSample(string name)
        {
#if UNITY_EDITOR
            Profiler.BeginSample(name);
#endif
        }

        public static void EndSample()
        {
#if UNITY_EDITOR
            Profiler.EndSample();
#endif
        }

    }
}

